package org.agony2d.display.core {
	import flash.display.DisplayObject;
	import flash.geom.Point;
	import org.agony2d.core.agony_internal;
	import org.agony2d.display.core.supportClasses.FusionComp;
	import org.agony2d.display.core.supportClasses.NodeComp;
	import org.agony2d.display.core.supportClasses.RecyclableComp;
	import org.agony2d.display.FusionUU;
	
	use namespace agony_internal;
	
	[Event(name = "press",   type = "org.agony2d.notify.AEvent")] 
	[Event(name = "release", type = "org.agony2d.notify.AEvent")] 
	[Event(name = "over",    type = "org.agony2d.notify.AEvent")] 
	[Event(name = "leave",   type = "org.agony2d.notify.AEvent")] 
	[Event(name = "move",    type = "org.agony2d.notify.AEvent")] 
	[Event(name = "click",   type = "org.agony2d.notify.AEvent")]
	
	/** [ NodeUU ]
	 *  [◆]
	 * 		1.  x × y
	 * 		2.  width × height
	 * 		3.  scaleX × scaleY × rotation
	 * 		4.  alpha
	 * 		5.  visible × interactive
	 * 		6.  filters
	 * 
	 * 		7.  spaceWidth × spaceHeight
	 * 		8.  userData
	 * 		9.  fusion
	 *  	10. displayObject
	 *  	11. dragging × draggingInBounds
	 *  [◆◆]
	 * 		1.  globalToLocal × localToGlobal
	 * 		2.	setGlobalCoord
	 *  	3.  hitTestPoint
	 *  	4.  kill
	 * 		5.  addEventListener
	 * 		6.  removeEventListener
	 * 		7.  removeEventAllListeners
	 * 
	 * 		8.  drag
	 *  	9.  dragLockCenter
	 */
public class NodeUU {
	
	public function get x() : Number {
		return shell.x / m_pixelRatio
	}
	
	public function set x( v:Number ) : void {
		shell.x = v * m_pixelRatio
	}
	
	public function get y() : Number {
		return shell.y / m_pixelRatio
	}
	
	public function set y( v:Number ) : void {
		shell.y = v * m_pixelRatio
	}
	
	public function get width() : Number { 
		return view.width / m_pixelRatio 
	}
	
	public function get height () : Number { 
		return view.height / m_pixelRatio 
	}
	
	public function get scaleX () : Number { 
		return shell.m_scaleX 
	}
	
	public function set scaleX ( v:Number ) : void { 
		shell.scaleX = v 
	}
	
	public function get scaleY () : Number { 
		return shell.m_scaleY 
	}
	
	public function set scaleY ( v:Number ) : void { 
		shell.scaleY = v 
	}
	
	public function get rotation () : Number { 
		return shell.m_rotation 
	}
	
	public function set rotation ( v:Number ) : void { 
		shell.rotation = v 
	}
	
	public function get alpha () : Number { 
		return shell.m_alpha
	}
	
	public function set alpha ( v:Number ) : void { 
		shell.alpha = v 
	}
	
	public function get visible () : Boolean { 
		return view.visible 
	}
	
	public function set visible ( b:Boolean ) : void { 
		view.visible = b 
	}
	
	public function get interactive () : Boolean {
		return m_dragging ? cachedInteractive : view.interactive
	}
	
	public function set interactive ( b:Boolean ) : void { 
		if (m_dragging) {
			cachedInteractive = b
		}
		else {
			view.interactive = b 
		}
	}
	
	public function get filters () : Array { 
		return view.filters
	}
	
	public function set filters ( v:Array ) : void { 
		view.filters = v 
	}
	
	public function get spaceWidth() : Number {
		return (m_spaceWidth <= 0 || isNaN(m_spaceWidth)) ? view.width / m_pixelRatio : m_spaceWidth
	}
	
	public function set spaceWidth( v:Number ) : void {
		m_spaceWidth = v
	}
	
	public function get spaceHeight() : Number {
		return (m_spaceHeight <= 0 || isNaN(m_spaceHeight)) ? view.height / m_pixelRatio : m_spaceHeight
	}
	
	public function set spaceHeight( v:Number ) : void { 
		m_spaceHeight = v 
	}
	
	public function get userData() : Object { 
		return m_userData
	}
	
	public function set userData( v:Object ) : void { 
		m_userData = v 
	}
	
	public function get fusion() : FusionUU {
		return m_parent ? m_parent.m_proxy as FusionUU : null
	}
	
	public function get displayObject() : DisplayObject { 
		return shell 
	}
	
	public function globalToLocal( globalX:Number, globalY:Number, result:Point = null ) : Point {
		if (!result) {
			result = new Point
		}
		g_cachedPoint.setTo(globalX * m_pixelRatio, globalY * m_pixelRatio)
		result = view.globalToLocal(g_cachedPoint)
		result.setTo(result.x / m_pixelRatio , result.y / m_pixelRatio)
		return result
	}
	
	public function localToGlobal( localX:Number, localY:Number, result:Point = null ) : Point {
		if (!result) {
			result = new Point
		}
		g_cachedPoint.setTo(localX * m_pixelRatio, localY * m_pixelRatio)
		result = view.localToGlobal(g_cachedPoint)
		result.setTo(result.x / m_pixelRatio , result.y / m_pixelRatio)
		return result
	}
	
	/** 使用前，先加入到父合体 */
	public function setGlobalCoord( globalX:Number, globalY:Number ) : void {
		var point:Point
		var comp:RecyclableComp
		
		g_cachedPoint.setTo(globalX * m_pixelRatio, globalY * m_pixelRatio)
		comp             =  this.shell
		point            =  comp.parent.globalToLocal(g_cachedPoint)
		comp.x           =  point.x
		comp.y           =  point.y
	}
	
	/** use global coords */
	public function hitTestPoint( globalX:Number, globalY:Number ) : Boolean {
		return view.hitTestPoint(globalX * m_pixelRatio, globalY * m_pixelRatio)
	}	
	
	public function addEventListener( type:String, listener:Function, priority:int = 0 ) : void {
		view.m_notifier.addEventListener(type, listener, priority)
	}
	
	public function removeEventListener( type:String, listener:Function ) : void {
		view.m_notifier.removeEventListener(type, listener)
	}
	
	public function removeEventAllListeners( type:String ) : void {
		view.m_notifier.removeEventAllListeners(type)
	}
	
	public function hasEventListener( type:String ) : Boolean {
		return view.m_notifier.hasEventListener(type)
	}
	
	public function kill() : void {
		if(m_parent) {
			(m_parent.m_proxy as FusionUU).removeElement(this)
		}
		super.dispose()
	}
	
	
	agony_internal static var g_cachedPoint:Point
	agony_internal static var m_pixelRatio:Number
	
	agony_internal var m_parent:FusionComp
	agony_internal var m_spaceWidth:Number
	agony_internal var m_spaceHeight:Number
	agony_internal var m_userData:Object
	
	
	
	/** 内部(本地坐标，是否可见，可交互) */
	agony_internal function get view() : NodeComp { 
		return null 
	}
	
	/** 外部 (外部坐标，角度，缩放，透明度) */
	agony_internal function get shell() : RecyclableComp { 
		return null 
	}
	
	/** overwrite */
	agony_internal function makeTransform( smoothing:Boolean, external:Boolean ) : void {
		
	}
	
}
}